﻿//-----------------------------------------------------------------------
// <copyright file="UnitTestMustHaveDescription.cs" company="COMPANY">
//     Copyright (c) COPYRIGHT. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace CodeQualityExtension.UnitTestRules
{
    using System;
    using System.Linq;
    using CodeQualityExtension.Framework;
    using Microsoft.FxCop.Sdk;

    /// <summary>
    /// Checks whether unit test methods are marked with DescriptionAttribute 
    /// </summary>
    public class UnitTestMustHaveDescription : BaseRule
    {
        /// <summary>
        /// Full name of DescriptionAttribute
        /// </summary>
        internal const string DescriptionAttributeFullName =
            "Microsoft.VisualStudio.TestTools.UnitTesting.DescriptionAttribute";
        
        /// <summary>
        /// Initializes a new instance of the UnitTestMustHaveDescription class
        /// </summary>
        public UnitTestMustHaveDescription() 
            : base(typeof(UnitTestMustHaveDescription))
        {
        }

        /// <summary>
        /// Checks only externally visible members
        /// </summary>
        public override TargetVisibilities TargetVisibility
        {
            get
            {
                return TargetVisibilities.ExternallyVisible;
            }
        }

        /// <summary>
        /// Checks if all test methods are marked by DescriptionAttribute 
        /// </summary>
        /// <param name="member">FxCop member instance</param>
        /// <returns>Collection of problems</returns>
        public override ProblemCollection Check(Member member)
        {
            Method method = member as Method;
            if (method != null && InternalUtilities.IsTestMethod(method))
            {
                if (!method.HasAttribute(DescriptionAttributeFullName))
                {
                    // SourceContext enables to display hyperlink to method declaration
                    Problem problem = new Problem(
                        GetResolution(method.Name.Name),
                        member.SourceContext);

                    this.Problems.Add(problem);
                }
            }
            
            return this.Problems;
        }
    }
}